package dsc;

/*
 * Deze methodes uit deze klasse worden alleen aangeroepen door de
 * MessageHandler of dePinger die de opdracht geeft om berichten
 * naar de gespecifeerde bestemmingen te sturen. Maakt eigenlijk alleen de
 * header aan van ieder bericht.
 */

import java.io.*;
import java.net.*;
import java.util.logging.Logger;

/**
 * 
 */
public class MessageCreator extends Thread {

	Logging logInstance = new Logging(MessageHandler.class.getName());
	Logger logger;
	DatagramSocket dSocket;
	InetAddress address;
	int port, messagenumber = 0;
	byte[] receiveData = new byte[1024];
	Integer length = 1;

	public MessageCreator(DatagramSocket socket) throws IOException {
		dSocket = socket;
		initLogger();
	}
	
	public void initLogger() {
		logger = logInstance.createLogger();
		try {
			logInstance.init(logger);
		} catch (Exception e) {
		}
	}

	/**
	 * Converteer een int naar byte array
         * @param value
         * @return byte []
	 */
	public static final byte[] intToByteArray(int value) {
		return new byte[] { (byte) (value >> 8 & 0xff), (byte) (value & 0xff) };
	}

	/**
	 * Bouwt de header op in byte formaat
         * @param messagenumber
         * @param messagetype
         * @param msglength
         * @return byte []
	 */
	private byte[] msgPacker(int msglength, int messagetype, int messagenumber,
			byte[] msg) {
		int i, count = 0;
		byte[] pckdmsg = new byte[msglength + 6];
		byte[] temp;

		temp = intToByteArray(pckdmsg.length);
		for (i = 0; i < temp.length; i++) {
			pckdmsg[count++] = temp[i];
		}

		temp = intToByteArray(messagetype);
		for (i = 0; i < temp.length; i++) {
			pckdmsg[count++] = temp[i];
		}

		temp = intToByteArray(messagenumber);
		for (i = 0; i < temp.length; i++) {
			pckdmsg[count++] = temp[i];
		}

		for (i = 0; i < msg.length; i++) {
			pckdmsg[count++] = msg[i];
		}
		return pckdmsg;

	}
	
        /*
	 * Dit bericht wordt verstuurd wanneer een lijst met clieten gegeven moet
	 * aan clienten en servers.
         * @param device
         * @param message
         * @return void
	 */
	public void msg110(ConnectedDevices device, byte[] message) {
		byte[] pckdmsg = msgPacker(message.length, 110, device.getVolgnummer(),
				message);
		try {
			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					device.getIpadress(), device.getPort());
			dSocket.send(data);

			logger.info("vn:" + device.getVolgnummer() + " IP: "
					+ device.getIpadress() + " message 110 sent" + " Tag:"
					+ device.getTag());
			device.upVolgnummer();
		} catch (Exception ex) {
			logger.severe("something went wrong in msg110");
		}

	}

	/*
	 * Dit bericht wordt verstuurd wanneer er een Client verwijderd wordt en dit
	 * bekend gemaakt moet worden aan het netwerk.
         * @param device
         * @param message
	 */
	public void msg130(ConnectedDevices device, byte[] message) {
		byte[] pckdmsg = msgPacker(message.length, 130, device.getVolgnummer(),
				message);
		try {
			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					device.getIpadress(), device.getPort());
			dSocket.send(data);
			logger.info("vn: " + device.getVolgnummer() + " IP: "
					+ device.getIpadress() + " message 130 sent" + " Tag: "
					+ device.getTag());
			device.upVolgnummer();
		} catch (Exception ex) {
			logger.severe("something went wrong in msg130");
		}
	}

	/*
	 * Dit bericht wordt verzonden wanneer er een Ping verstuur moet worden.
         * @param device
         * @param message
	 */
	public void msg140(ConnectedDevices device, byte[] ident) {
		byte[] pckdmsg = msgPacker(ident.length, 140, device.getVolgnummer(),
				ident);

		try {
			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					device.getIpadress(), device.getPort());
			dSocket.send(data);

			logger.info("vn: " + device.getVolgnummer() + " IP: "
					+ device.getIpadress() + " message 140 sent" + " Tag: "
					+ device.getTag());
			device.upVolgnummer();
		} catch (Exception ex) {
			logger.severe("something went wrong in msg140");
		}
	}

	/*
	 * Dit bericht wordt verzonden wanneer er een ping wordt gestuurd door de
	 * controlserver
         * @param device
         * @param message
	 */
	public void msg150(InetAddress address, int port, byte[] ident) {
		byte[] pckdmsg = msgPacker(ident.length, 150, messagenumber, ident);

		try {
			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					address, port);
			dSocket.send(data);
			logger.info("vn: " + messagenumber + " IP: " + address
					+ " message 150 sent to CS");
			messagenumber++;
		} catch (Exception ex) {
			logger.severe("something went wrong in msg150");
		}
	}

	/*
	 * Dit bericht wordt verzonden wanneer er een ping is ontvangen door iemand
	 * op het netwerk. Dus een pong.
         * @param device
         * @param message
	 */
	public void msg150(ConnectedDevices device, byte[] message) {

		byte[] pckdmsg = msgPacker(message.length, 150, device.getVolgnummer(),
				message);
		logger.info(Integer.toString(message.length) + Integer.toString(110)
				+ Integer.toString(device.getVolgnummer())
				+ MessageHandler.byteArrayToString(message));
		try {
			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					device.getIpadress(), device.getPort());
			dSocket.send(data);
			logger.info("vn: " + device.getVolgnummer() + "  IP: "
					+ device.getIpadress() + " message 150 sent" + " Tag:"
					+ device.getTag());
			device.upVolgnummer();
		} catch (Exception ex) {
			logger.severe("something went wrong in msg150");
		}
	}

	/*
	 * Dit bericht wordt verzonden wanneer een Naamwijziging is gelukt en het
	 * bekend gemaakt moet worden aan de rest van het netwerk.
         * @param device
         * @param message
	 */
	public void msg170(ConnectedDevices device, byte[] message) {
		byte[] pckdmsg = msgPacker(message.length, 170, device.getVolgnummer(),
				message);
		logger.info(Integer.toString(message.length) + Integer.toString(110)
				+ Integer.toString(device.getVolgnummer())
				+ MessageHandler.byteArrayToString(message));
		try {
			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					device.getIpadress(), device.getPort());
			dSocket.send(data);
			logger.info("vn: " + device.getVolgnummer() + "  IP: "
					+ device.getIpadress() + " message 170 sent" + "  Tag: "
					+ device.getTag());
			device.upVolgnummer();
		} catch (Exception ex) {
			logger.severe("something went wrong in msg170");
		}
	}

	/*
	 * Dit bericht wordt verzonden wanneer er een tekstbericht binnen is
	 * gekomen.
         * @param device
         * @param message
	 */
	public void msg300(ConnectedDevices device, byte[] message) {
		byte[] pckdmsg = msgPacker(message.length, 300, device.getVolgnummer(),
				message);
		logger.info(Integer.toString(message.length) + Integer.toString(110)
				+ Integer.toString(device.getVolgnummer())
				+ MessageHandler.byteArrayToString(message));

		try {
			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					device.getIpadress(), device.getPort());
			dSocket.send(data);
			logger.info("vn: " + device.getVolgnummer() + "  IP: "
					+ device.getIpadress() + " message 300 sent" + "  Tag: "
					+ device.getTag());
			device.upVolgnummer();
		} catch (Exception ex) {
			logger.severe("something went wrong in msg210");
		}
	}

	/*
	 * Dit bericht wordt verstuurd wanneer er een acite bericht is binnen
	 * gekomen.
         * @param device
         * @param message
         */
	public void msg310(ConnectedDevices device, byte[] message) {
		byte[] pckdmsg = msgPacker(message.length, 310, device.getVolgnummer(),
				message);
		logger.info(Integer.toString(message.length) + Integer.toString(110)
				+ Integer.toString(device.getVolgnummer())
				+ MessageHandler.byteArrayToString(message));

		try {
			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					device.getIpadress(), device.getPort());
			dSocket.send(data);
			logger.info("vn: " + device.getVolgnummer() + "  IP: "
					+ device.getIpadress() + " message 310 sent" + "  Tag: "
					+ device.getTag());
			device.upVolgnummer();
		} catch (Exception ex) {
			logger.severe("something went wrong in msg210");
		}
	}

	/*
	 * Dit bericht wordt verzonden wanneer de registratie van een client gelukt
	 * is.
         * @param device
         * @param message
	 */
	public void msg500(ConnectedDevices device, byte[] message) {
		byte[] pckdmsg = msgPacker(message.length, 500, device.getVolgnummer(),
				message);
		logger.info(Integer.toString(message.length) + Integer.toString(110)
				+ Integer.toString(device.getVolgnummer())
				+ MessageHandler.byteArrayToString(message));

		try {
			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					device.getIpadress(), device.getPort());
			dSocket.send(data);
			logger.info("vn: " + device.getVolgnummer() + "  IP: "
					+ device.getIpadress() + " message 500 sent" + "  Tag: "
					+ device.getTag());
			device.upVolgnummer();
		} catch (Exception ex) {
			logger.severe("something went wrong in msg500");
		}
	}

	/*
	 * Dit bericht wordt verzonden wanneer een registratie van een Client
	 * mislukt is.
         * @param device
         * @param message
	 */
	public void msg510(ConnectedDevices device, byte[] message) {
		byte[] pckdmsg = msgPacker(message.length, 510, device.getVolgnummer(),
				message);
		logger.info(Integer.toString(message.length) + Integer.toString(110)
				+ Integer.toString(device.getVolgnummer())
				+ MessageHandler.byteArrayToString(message));

		try {
			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					device.getIpadress(), device.getPort());
			dSocket.send(data);
			logger.info("vn: " + device.getVolgnummer() + "  IP: "
					+ device.getIpadress() + " message 510 sent" + "  Tag: "
					+ device.getTag());
			device.upVolgnummer();
		} catch (Exception ex) {
			logger.severe("something went wrong in msg510");
		}
	}

	/*
	 * Dit bericht wordt verzonden wanneer een naamwijziging gelukt is.
         * @param device
         * @param message
	 */
	public void msg520(ConnectedDevices device, byte[] message) {
		byte[] pckdmsg = msgPacker(message.length, 520, device.getVolgnummer(),
				message);
		logger.info(Integer.toString(message.length) + Integer.toString(110)
				+ Integer.toString(device.getVolgnummer())
				+ MessageHandler.byteArrayToString(message));

		try {
			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					device.getIpadress(), device.getPort());
			dSocket.send(data);
			logger.info("vn: " + device.getVolgnummer() + "  IP: "
					+ device.getIpadress() + " message 520 sent" + "  Tag: "
					+ device.getTag());
			device.upVolgnummer();
		} catch (Exception ex) {
			logger.severe("something went wrong in msg520");
		}

	}

	/*
	 * Dit bericht wordt gestuurd wanneer een naamwijziging is mislukt.
         * @param device
         * @param message
	 */
	public void msg530(ConnectedDevices device, byte[] message) {
		byte[] pckdmsg = msgPacker(message.length, 530, device.getVolgnummer(),
				message);
		logger.info(Integer.toString(message.length) + Integer.toString(110)
				+ Integer.toString(device.getVolgnummer())
				+ MessageHandler.byteArrayToString(message));

		try {
			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					device.getIpadress(), device.getPort());
			dSocket.send(data);
			logger.info("vn: " + device.getVolgnummer() + "  IP: "
					+ device.getIpadress() + " message 530 sent" + "  Tag: "
					+ device.getTag());
			device.upVolgnummer();
		} catch (Exception ex) {
			logger.severe("something went wrong in msg530");
		}

	}

	/*
	 * Dit is een Server Server bericht voor het aanmelden, om in de boom te
	 * komen De server identifier wordt als een byte array meegegeven.
         * @param device
         * @param message
	 */
	public void msg600(ConnectedDevices device, byte[] ident) {
		byte[] pckdmsg = msgPacker(ident.length, 600, device.getVolgnummer(),
				ident);
		logger.info(Integer.toString(ident.length) + Integer.toString(110)
				+ Integer.toString(device.getVolgnummer())
				+ MessageHandler.byteArrayToString(ident));

		try {
			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					device.getIpadress(), device.getPort());
			dSocket.send(data);
			logger.info("vn: " + device.getVolgnummer() + "  IP: "
					+ device.getIpadress() + " message 600 sent" + "  Tag: "
					+ device.getTag());
			device.upVolgnummer();
		} catch (Exception ex) {
			logger.severe("something went wrong in msg600");
		}

	}

	/*
	 * Dit bericht wordt verzonden als de server zich wilt aanmelden bij
         * de control server om deel te nemen aan het netwerk.
         * @param device
         * @param message
	 */
	public void msg601(InetAddress address, int port, byte[] message) {
		try {
			byte[] pckdmsg = msgPacker(message.length, 601, messagenumber,
					message);
			logger.info(Integer.toString(message.length)
					+ Integer.toString(110) + Integer.toString(messagenumber)
					+ MessageHandler.byteArrayToString(message));

			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					address, port);
			// if(data.getAddress().isMulticastAddress()) {
			logger.info(data.getPort() + " " + data.getLength() + " "
					+ data.getAddress());
			messagenumber++;
			dSocket.send(data);
			// }
			// else{
			// logger.severe("Can't send a message to this address");
			// }
			logger.info("message 601 sent to CS");
		} catch (Exception ex) {
			logger.severe("something went wrong in msg601");
		}
	}

	/*
	 * Wordt verstuurd als een device niet reageert. Dit laat de controlserver
	 * weten dat hij niet reageert.
         * @param device
         * @param message
	 */

	public void msg603(InetAddress address, int port, byte[] message) {
		byte[] pckdmsg = msgPacker(message.length, 603, messagenumber, message);
		logger.info(Integer.toString(message.length) + " "
				+ Integer.toString(603) + " " + Integer.toString(messagenumber)
				+ " " + MessageHandler.byteArrayToString(message));

		try {
			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					address, port);
			dSocket.send(data);
			logger.info("vn: " + messagenumber + "  IP: " + address
					+ " message 603 sent");

			messagenumber++;
		} catch (Exception ex) {
			logger.severe("something went wrong in msg600");
		}

	}
        /*
	 * Dit wordt verstuurd wanneer een admin wilt dat een server van het
         * netwerk verwijderd wordt.
         * @param device
         * @param message
	 */
        public void msg700(ConnectedDevices device, byte[] message) {
		byte[] pckdmsg = msgPacker(message.length, 700, device.getVolgnummer(),
				message);
		logger.info(Integer.toString(message.length) + Integer.toString(110)
				+ Integer.toString(device.getVolgnummer())
				+ MessageHandler.byteArrayToString(message));

		try {
			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					device.getIpadress(), device.getPort());
			dSocket.send(data);
			logger.info("vn: " + device.getVolgnummer() + "  IP: "
					+ device.getIpadress() + " message 700 sent" + "  Tag: "
					+ device.getTag());
			device.upVolgnummer();
		} catch (Exception ex) {
			logger.severe("something went wrong in msg701");
		}

	}
        
        /**
	 * Wordt verstuurd als een device niet reageert. Dit laat de controlserver
	 * weten dat hij niet reageert.
         * @param device
         * @param message
         */
	public void msg701(ConnectedDevices device, byte[] message) {
		byte[] pckdmsg = msgPacker(message.length, 701, device.getVolgnummer(),
				message);
		logger.info(Integer.toString(message.length) + Integer.toString(110)
				+ Integer.toString(device.getVolgnummer())
				+ MessageHandler.byteArrayToString(message));

		try {
			DatagramPacket data = new DatagramPacket(pckdmsg, pckdmsg.length,
					device.getIpadress(), device.getPort());
			dSocket.send(data);
			logger.info("vn: " + device.getVolgnummer() + "  IP: "
					+ device.getIpadress() + " message 701 sent" + "  Tag: "
					+ device.getTag());
			device.upVolgnummer();
		} catch (Exception ex) {
			logger.severe("something went wrong in msg701");
		}

	}

}
